import uuid

import cv2
import numpy as np
import tensorflow as tf

from com.haojiangbo.utils import DrawUtils


class CharUtl:
    rectArray = []
    # 传入的是 原图的灰度图
    binaryImg = []
    srcImages = []
    newModel = None
    isDebuger = False

    def __init__(self, modelPath, isDebuger):
        self.isDebuger = isDebuger
        print("loading model ...")
        self.newModel = tf.keras.models.load_model(modelPath)
        print("loading model ok")

    """
        检测这个输入种的字符串，转为二值图，返回一个带有坐标的集合对象
    """

    def showImages(self, binaryImg, srcImages):
        listRect, pointList = self.__findContoursImages(binaryImg, srcImages)
        tmpMat = srcImages
        predTestData = []
        for index in range(len(listRect)):
            tmp = 255 - listRect[index]
            t, binaryImg = cv2.threshold(tmp, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
            binaryImg = cv2.resize(binaryImg, (32, 40))
            binaryImg = binaryImg.reshape(len(binaryImg), len(binaryImg[0]), 1)
            binaryImg = binaryImg / 255.0
            predTestData.append(binaryImg)
        if len(predTestData) < 1:
            return "未检测到数据"
        val = self.newModel.predict(np.array(predTestData))
        val = tf.nn.softmax(val)
        pred = tf.argmax(val, axis=1)
        predValuePointArray = []
        for index in range(len(pred)):
            preValue = self.__valueHandler(int(pred[index]))
            if self.isDebuger:
                print("pred == {} point = {}".format(preValue, pointList[index]))
            if pointList[index][0] > 170 and pointList[index][1] > 300:
                predValuePointArray.append((pointList[index][0], str(preValue)))

        predValuePointArray.sort(key=lambda x: x[0])
        codeStr = ""
        for item in predValuePointArray:
            codeStr += str(item[1])

        if self.isDebuger:
            du = DrawUtils.MyDrawUtils()
            tmpMat = du.drawText2(tmpMat, 140, 300, codeStr, (0, 0, 255))
            cv2.imshow("result", tmpMat)
            cv2.waitKey(0)
            cv2.destroyWindow("result")

        return codeStr

    def __findContoursImages(self, binaryImg, srcImages):
        self.binaryImg = binaryImg
        self.srcImages = srcImages

        if self.isDebuger:
            cv2.imshow("bimg", binaryImg)
            cv2.waitKey(0)
            cv2.destroyWindow("bimg")

        # RETR_EXTERNAL   RETR_LIST
        contours, hierarchy = cv2.findContours(self.binaryImg, mode=cv2.RETR_LIST, method=cv2.CHAIN_APPROX_SIMPLE)
        listRect = []
        pointList = []
        tmpList = []

        for index in range(len(contours)):
            # 轮廓拟合，
            x, y, w, h = cv2.boundingRect(contours[index])
            area = w * h
            # 如果面积在这个范围内 就加入识别集合
            if 100 < area < 1000:
                if self.isDebuger:
                    brcnt = np.array([[x, y], [x + w, y], [x + w, y + h], [x, y + h]])
                    tmpList.append(brcnt)
                    print("index = {}  area = {} w = {}  h = {} radio = {}".format(index, area, w, h, abs(w / h)))
                listRect.append(self.srcImages[y:y + h, x:x + w])
                pointList.append((x, y))

        if self.isDebuger:
            dst = cv2.drawContours(binaryImg, tmpList, -1, color=(255, 255, 255), thickness=1)
            cv2.imshow("marker", dst)
            cv2.waitKey(0)
            cv2.destroyWindow("marker")
        return listRect, pointList

    def __valueHandler(self, index):
        if index < 10:
            return index
        elif index == 10:
            return "X"
        return "?"
